﻿using System;
using System.Collections.Generic;
using Sapit.Attributes.Interfaces;
using Sapit.Helpers;

namespace Sapit.Base
{
    public abstract class CircuitBreakerBase
    {
        private static Dictionary<Invocation, TimedValue<int>> failedInvocations = new Dictionary<Invocation, TimedValue<int>>();

        protected static bool ThisInvocationIsShutOff(Invocation invocation, ICircuitBreaker circuitBreaker)
        {
            return
                failedInvocations.ContainsKey(invocation) && // The invocation failed last time
                failedInvocations[invocation].Value >= circuitBreaker.MaxConsecutiveFailures; // The invocation has exceeded max consecutive failures
        }

        protected static bool ThisInvocationShouldBeTurnedBackOn(Invocation inv, ICircuitBreaker circuitBreaker)
        {
            return
                failedInvocations[inv].When.AddSeconds(circuitBreaker.ShutOffPeriodSeconds) < DateTime.Now; // The invocation is in the shut off period
        }

        protected static void TurnThisInvocationBackOn(Invocation invocation)
        {
            failedInvocations.Remove(invocation);
        }

        protected static void RegisterFailure(Invocation invocation)
        {
            if (failedInvocations.ContainsKey(invocation))
            {
                failedInvocations[invocation].Value += 1;
            }
            else
            {
                failedInvocations.Add(invocation, new TimedValue<int>() { Value = 1, When = DateTime.Now });
            }
        }
    }
}
